package com.ciaojian.core.service;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ciaojian.core.constant.RedisConstant;
import com.ciaojian.core.enums.business.CouponCodeOriginEnum;
import com.ciaojian.core.mapper.CouponCodeMapper;
import com.ciaojian.core.mapper.CouponCodeMemberDetailMapper;
import com.ciaojian.core.mapper.CouponMapper;
import com.ciaojian.core.model.*;
import com.ciaojian.core.util.LogUtil;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 券码-权益 关联表 服务类
 * </p>
 *
 * @author Atlakyn
 * @since 2021-04-12
 */
public abstract class CouponCodeMemberDetailService<M extends BaseMapper<T>, T> extends ServiceImpl<CouponCodeMemberDetailMapper, CouponCodeMemberDetail> {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private CouponCodeService<CouponCodeMapper, CouponCode> couponCodeService;
    @Resource
    private CouponService<CouponMapper, Coupon> couponService;

    public void getCouponByPackage(Integer couponId,
                                   Integer userId,
                                   MemberDetail memberDetail,
                                   Order order) {
        // 取一张券
        CouponCode stock = couponCodeService.getStock(couponId);
        // redis 中锁住的券
        Object stockRedis = redisTemplate.opsForValue().get(RedisConstant.COUPON_CODE.concat(String.valueOf(stock.getId())));
        // 如果不为空表示被别人先锁了,先退出程序
        if (stockRedis != null) {
            return;
        }
        // 先锁住这张券
        redisTemplate.opsForValue().setIfAbsent(RedisConstant.COUPON_CODE.concat(String.valueOf(stock.getId())), stock, 15, TimeUnit.SECONDS);
        stock.setUserId(userId);
        stock.setOrigin(CouponCodeOriginEnum.BUY_MEMBER_DETAIL);
        stock.setOrderId(order != null ? order.getId() : null);
        stock.setStatus(1);
        if (stock.updateById()) {
            CouponCodeMemberDetail couponCodeMemberDetail = new CouponCodeMemberDetail();
            couponCodeMemberDetail.setCouponCodeId(stock.getId());
            couponCodeMemberDetail.setMemberDetailId(memberDetail.getId());
            try {
                couponCodeMemberDetail.insert();
                // 券数量+1
                couponService.addGetNum(memberDetail.getCouponId());
            } catch (Exception e) {
                LogUtil.writeErrorLog(e.getMessage());
            } finally {
                // 操作完成 释放redis中的内存
                redisTemplate.delete(RedisConstant.COUPON_CODE.concat(String.valueOf(stock.getId())));
            }
        } else {
            LogUtil.writeBusinessLog(String.format("券码发放失败,用户:{%s},券id:{%s},origin:{%s}", userId, memberDetail.getCouponId(), CouponCodeOriginEnum.BUY_MEMBER_DETAIL));
        }
    }
}
